﻿using System;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MugenMvvmToolkit;
using MugenMvvmToolkit.ViewModels;
using MugenMvvmToolkit.Interfaces;
using MugenMvvmToolkit.Ioc;
using Ninject;
using Should;

namespace MugenMvvmToolkitTest.Ioc
{
    [TestClass]
    public class NinjectIocAdapterTest : IocAdapterBaseTest<NinjectIocAdapter>
    {
        #region Constructors

        public NinjectIocAdapterTest()
            : base(() => new NinjectIocAdapter(new StandardKernel()))
        {
        }

        #endregion

        #region Overrides of IocAdapterBaseTest<NinjectIocAdapter>

        [TestMethod]
        public override void TestBindToTypeNamed()
        {
            const string named = "named";

            using (IIocAdapter iocAdapter = GetIocAdapter())
            {
                iocAdapter.Bind<ISimple, Simple>(DependencyLifecycle.SingleInstance, named);

                var simple = (ISimple)iocAdapter.Get(typeof(ISimple), named);
                simple.ShouldNotBeNull();
                iocAdapter.Get<ISimple>(named).ShouldEqual(simple);
                iocAdapter.Get(typeof(ISimple), named).ShouldEqual(simple);
            }

            using (IIocAdapter iocAdapter = GetIocAdapter())
            {
                iocAdapter.Bind(typeof(ISimple), typeof(Simple), DependencyLifecycle.SingleInstance, named);

                var simple = (ISimple)iocAdapter.Get(typeof(ISimple), named);
                simple.ShouldNotBeNull();
                iocAdapter.Get<ISimple>(named).ShouldEqual(simple);
                iocAdapter.Get(typeof(ISimple), named).ShouldEqual(simple);
            }

            using (IIocAdapter iocAdapter = GetIocAdapter())
            {
                iocAdapter.Bind<ISimple, Simple>(DependencyLifecycle.TransientScopeInstance, named);

                var simple = (ISimple)iocAdapter.Get(typeof(ISimple), named);
                simple.ShouldNotBeNull();
                iocAdapter.Get<ISimple>(named).ShouldNotEqual(simple);
                iocAdapter.Get(typeof(ISimple), named).ShouldNotEqual(simple);
            }

            using (IIocAdapter iocAdapter = GetIocAdapter())
            {
                iocAdapter.Bind(typeof(ISimple), typeof(Simple), DependencyLifecycle.TransientScopeInstance, named);

                var simple = (ISimple)iocAdapter.Get(typeof(ISimple), named);
                simple.ShouldNotBeNull();
                iocAdapter.Get<ISimple>(named).ShouldNotEqual(simple);
                iocAdapter.Get(typeof(ISimple), named).ShouldNotEqual(simple);
            }
        }

        [TestMethod]
        public override void TestBindToConstantNamed()
        {
            const string named = "named";

            using (IIocAdapter iocAdapter = GetIocAdapter())
            {
                var constValue = new Simple();
                iocAdapter.BindToConstant<ISimple>(constValue, named);

                var simple = (ISimple)iocAdapter.Get(typeof(ISimple), named);
                simple.ShouldNotBeNull();
                simple.ShouldEqual(constValue);
                iocAdapter.Get<ISimple>(named).ShouldEqual(simple);
                iocAdapter.Get(typeof(ISimple), named).ShouldEqual(simple);
            }

            using (IIocAdapter iocAdapter = GetIocAdapter())
            {
                var constValue = new Simple();
                iocAdapter.BindToConstant(typeof(ISimple), constValue, named);

                var simple = (ISimple)iocAdapter.Get(typeof(ISimple), named);
                simple.ShouldNotBeNull();
                simple.ShouldEqual(constValue);
                iocAdapter.Get<ISimple>(named).ShouldEqual(simple);
                iocAdapter.Get(typeof(ISimple), named).ShouldEqual(simple);
            }
        }

        [TestMethod]
        public override void TestUnbind()
        {
            using (IIocAdapter iocAdapter = GetIocAdapter())
            {
                var constValue = new Simple();
                iocAdapter.BindToConstant<ISimple>(constValue);

                iocAdapter.Get<ISimple>().ShouldEqual(constValue);

                iocAdapter.Unbind(typeof(ISimple));
                Action action = () => iocAdapter.Get<ISimple>().ShouldEqual(constValue);
                action.ShouldThrow();
            }
        }

        #endregion
    }
}